#include "qmemeryvaluesetdialog.h"

#include "../../include/qcommonstruct.h"
#include "../../lib/shared/qproject.h"
#include "qproperty.h"

#include <QItemDelegate>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QHBoxLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QPainter>

class QMemeryDelegate: public QItemDelegate
{
public:
    QMemeryDelegate(QObject* o):m_object(o){}
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    QSize   sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void    setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void    paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
protected:
    QObject*  m_object;
};

QWidget* QMemeryDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QWidget *w=NULL;
    QProject *p=QProject::project();

    if(index.column()==0)
    {
        QComboBox *co=new QComboBox(parent);
        co->addItems(m_object->property("designer_user_property").toStringList());
        w=co;
        co->setCurrentIndex(co->findText(index.data().toString()));
        co->setFrame(false);
        co->setCurrentIndex(0);
    }
    else if(index.column()==1)
    {
        QString name=index.model()->data(index.model()->index(index.row(),0)).toString();
        if(name!="")
        {
            QVariant v=m_object->property(name.toLocal8Bit());
            QComboBox *co=new QComboBox(parent);
            int count=p->getRuntimeDataCount();

            for(int i=0;i<count;i++)
            {
                QRuntimeData info=p->getRuntimeData(i);
                if(v.canConvert(info.value().type()))
                {
                    co->addItem(info.name());
                    co->setCurrentIndex(co->findText(index.data().toString()));
                }

            }
            w=co;
            co->setFrame(false);
        }
    }
    else if(index.column()==2)
    {
        QLineEdit* line=new QLineEdit(parent);
        line->setText(index.data().toString());
        w=line;
        line->setFrame(false);
    }


    return w;
}

void QMemeryDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    if(index.column()<2)
    {
        QComboBox *box=(QComboBox*)editor;
        model->setData(index,box->currentText(),Qt::DisplayRole);
    }
    else
    {
        QLineEdit *edit=(QLineEdit*)editor;
        model->setData(index,edit->text(),Qt::DisplayRole);
    }
}

void QMemeryDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QColor color=Qt::black;
    if(index.data(Qt::UserRole).toBool())
    {
        painter->fillRect(option.rect,Qt::gray);
        color=Qt::blue;
    }
    painter->setPen(color);
    QFont f=painter->font();
    f.setPointSize(10);
    painter->setFont(f);
    painter->drawText(option.rect,Qt::AlignCenter,index.data(Qt::DisplayRole).toString());
    painter->restore();
}

QSize QMemeryDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz=QItemDelegate::sizeHint(option,index);
    sz.setHeight(20);
    return sz;
}


QVariant    QMemeryModel::data(const QModelIndex &index, int role) const
{
    if(index.row()<0 || index.row()>=m_items.size())
    {
        return QVariant();
    }
    tagMemeryInfo item=m_items.at(index.row());
    if(role==Qt::DisplayRole || role==Qt::ToolTipRole || role==Qt::EditRole)
    {
        if(index.column()==0)
        {
            return QVariant(item.m_property);
        }
        else if(index.column()==1)
        {
            return QVariant(item.m_value);
        }
        else if(index.column()==2)
        {
            return QVariant(item.m_script);
        }
    }
    else if(role==Qt::UserRole)
    {
        return QVariant(item.m_select);
    }
    return QVariant();
}

bool    QMemeryModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(index.row()<0 || index.row()>=m_items.size())
    {
        return false;
    }
    tagMemeryInfo item=m_items.at(index.row());
    if(role==Qt::DisplayRole || role==Qt::EditRole)
    {
        if(index.column()==0)
        {
            item.m_property=value.toString();
        }
        else if(index.column()==1)
        {
            item.m_value=value.toString();
        }
        else if(index.column()==2)
        {
            item.m_script=value.toString();
        }
    }
    else if(role==Qt::UserRole)
    {
        item.m_select=value.toBool();
    }
    m_items.replace(index.row(),item);
    return true;
}

Qt::ItemFlags QMemeryModel::flags(const QModelIndex &index) const
{
    return Qt::ItemIsEditable | Qt::ItemIsEnabled;
}

int QMemeryModel::rowCount(const QModelIndex &parent) const
{
    return m_items.size();
}

void QMemeryModel::addItem()
{
    tagMemeryInfo item;
    item.m_property=item.m_value=item.m_script="";
    item.m_select=getSelect()==-1;
    beginInsertRows(QModelIndex(),m_items.size(),m_items.size());
    m_items.append(item);
    endInsertRows();
}

void QMemeryModel::AddItem(const tagMemeryInfo &info)
{
    tagMemeryInfo item;
    item.m_property=info.m_property;
    item.m_script=info.m_script;
    item.m_value=info.m_value;
    item.m_select=getSelect()==-1;
    beginInsertRows(QModelIndex(),m_items.size(),m_items.size());
    m_items.append(item);
    endInsertRows();
}

void QMemeryModel::removeSelectItem()
{
    int index=getSelect();
    if(index!=-1)
    {
        beginRemoveRows(QModelIndex(),index,index);
        m_items.removeAt(index);
        endRemoveRows();
    }
}

int QMemeryModel::getSelect()
{
    for(int i=0;i<m_items.size();i++)
    {
        if(m_items.at(i).m_select)
        {
            return i;
        }
    }
    return -1;
}

QList<tagMemeryInfo>    QMemeryModel::items()
{
    return m_items;
}

int QMemeryModel::columnCount(const QModelIndex &parent) const
{
    return 3;
}

QVariant QMemeryModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if(orientation==Qt::Horizontal)
    {
        QStringList list=QStringList()<<"Property"<<"Memery"<<"Script";
        if(role==Qt::DisplayRole || role==Qt::ToolTipRole)
        {
            return list.at(section);
        }
    }
    return QVariant();
}

QMemeryValueSetDialog::QMemeryValueSetDialog(QObject *o, QWidget *parent):
    QDialog(parent),
    m_treeWidget(new QTableView(this)),
    m_model(new QMemeryModel),
    m_addBtn(new QPushButton("Add",this)),
    m_removeBtn(new QPushButton("Remove",this)),
    m_okBtn(new QPushButton("Ok",this)),
    m_ret(0)
{
    this->setFixedSize(350,300);
    this->setWindowTitle("Memery Value");

    QVBoxLayout *l=new QVBoxLayout;
    l->setMargin(0);
    l->setSpacing(0);
    l->addWidget(m_treeWidget);
    m_treeWidget->setModel(m_model);
    m_treeWidget->verticalHeader()->hide();
    m_treeWidget->setItemDelegate(new QMemeryDelegate(o));

    QWidget *wid;

    wid=new QWidget(this);
    QHBoxLayout *h=new QHBoxLayout;
    h->addWidget(m_addBtn);
    h->addWidget(m_removeBtn);
    h->addWidget(m_okBtn);

    wid->setLayout(h);

    l->addWidget(wid);

    this->setLayout(l);

    m_addBtn->setFixedSize(100,30);
    m_removeBtn->setFixedSize(100,30);
    m_okBtn->setFixedSize(100,30);

    connect(m_addBtn,SIGNAL(clicked()),m_model,SLOT(addItem()));
    connect(m_removeBtn,SIGNAL(clicked()),m_model,SLOT(removeSelectItem()));
    connect(m_okBtn,SIGNAL(clicked()),this,SLOT(ok()));

    m_treeWidget->setColumnWidth(0,110);
    m_treeWidget->setColumnWidth(1,110);
    m_treeWidget->setColumnWidth(2,110);
    m_treeWidget->verticalHeader()->setDefaultSectionSize(18);

    connect(m_treeWidget,SIGNAL(pressed(QModelIndex)),this,SLOT(pressed(QModelIndex)));
}

void QMemeryValueSetDialog::ok()
{
    m_ret=1;
    close();
}

int QMemeryValueSetDialog::exec()
{
    QDialog::exec();
    return m_ret;
}

QVariant QMemeryValueSetDialog::value()
{
    MemeryValueItems items;
    QList<tagMemeryInfo>    list=m_model->items();

    foreach(tagMemeryInfo info,list)
    {
        if(info.m_property=="")
        {
            continue;
        }
        tagMemeryValueInfo in;
        in.m_propertyName=info.m_property;
        in.m_script=info.m_script;
        in.m_valueName=info.m_value;
        items.append(in);
    }
    QVariant v;
    v.setValue<MemeryValueItems>(items);
    return v;
}

void QMemeryValueSetDialog::setValue(const QVariant &v)
{
    MemeryValueItems items=v.value<MemeryValueItems>();
    foreach(tagMemeryValueInfo info,items)
    {
        tagMemeryInfo in;
        in.m_property=info.m_propertyName;
        in.m_script=info.m_script;
        in.m_value=info.m_valueName;
        m_model->AddItem(in);
    }
}

void QMemeryValueSetDialog::pressed(const QModelIndex &index)
{
    int n=m_model->getSelect();
    if(n!=index.row())
    {
        m_model->setData(m_model->index(n,0),false,Qt::UserRole);
        m_model->setData(index,true,Qt::UserRole);
        if(n>=0)
        {
            for(int i=0;i<3;i++)
            {
                m_treeWidget->update(m_model->index(n,i));
            }
        }
        for(int i=0;i<3;i++)
        {
            m_treeWidget->update(m_model->index(index.row(),i));
        }
    }
}
